﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EntityFrameworkETL.SaveBatchedChanges
{
    public class DbCommandCacheItem
    {
        public DbCommandCacheItem()
        {
            ChildCommands = new List<DbCommandCacheItem>();
        }
        public DbCommandCacheItem(long fakePk, DbCommand command) : this()
        {
            FakePk = fakePk;
            DbCommand = command;
            int iStart = command.CommandText.IndexOf(" ");
            int iEnd = command.CommandText.IndexOf("(");
            TableName = command.CommandText.Substring(iStart, iEnd - iStart).Trim();
            TableName = TableName.Replace("[", "");
            TableName = TableName.Replace("]", "");
        }

        public bool HasExecuted { get; set; }
        public string TableName { get; set; }
        public DbCommand DbCommand { get; set; }
        public string TypeName { get; set; }
        public long FakePk { get; set; }
        public object Entity { get; set; }
        public Type Type { get; set; }

        public List<DbCommandCacheItem> ChildCommands { get; set; }
        public DbCommandCacheItem ParentCommand { get; set; }
        public bool HasAncestor(DbCommandCacheItem currentDbCommand)
        {
            var currentparrent = this.ParentCommand;
            while (currentparrent != null)
            {
                if (currentparrent.TableName == currentDbCommand.TableName)
                    return true;

                currentparrent = currentparrent.ParentCommand;
            }
            return false;
        }
        public DbCommandCacheItem GetAncestor(DbCommandCacheItem currentDbCommand)
        {
            var currentparrent = this.ParentCommand;
            while (currentparrent != null)
            {
                if (currentparrent.TableName == currentDbCommand.TableName)
                    return currentparrent;

                currentparrent = currentparrent.ParentCommand;
            }
            return null;
        }

        public void SetId(int id)
        {
            var propertyInfo = Entity.GetType().GetProperties().Single(x => x.Name == "Id");
            propertyInfo.SetValue(Entity, id);
        }

        public void SetFks(int id)
        {
            foreach (var childCommand in ChildCommands)
            {
                foreach (DbParameter parameter in childCommand.DbCommand.Parameters)
                {
                    if (parameter.Value.ToString() == FakePk.ToString(CultureInfo.InvariantCulture))
                    {
                        parameter.Value = id;
                    }
                }
            }
        }
    }
}
